# 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。
# 如果 s 中不存在涵盖 t 所有字符的子串，则返回空字符串 "" 。
#
# 注意：
# 对于 t 中重复字符，我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
# 如果 s 中存在这样的子串，我们保证它是唯一的答案。
#
# 示例 1：
# 输入：s = "ADOBECODEBANC", t = "ABC"
# 输出："BANC"
#
# 示例 2：
# 输入：s = "a", t = "a"
# 输出："a"
#
# 示例 3:
# 输入: s = "a", t = "aa"
# 输出: ""
# 解释: t 中两个字符 'a' 均应包含在 s 的子串中，
# 因此没有符合条件的子字符串，返回空字符串。
#
# 提示：
# 1 <= s.length, t.length <= 105
# s 和 t 由英文字母组成
#
# 进阶：你能设计一个在 o(n) 时间内解决此问题的算法吗？
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need, window = {}, {}
        need_cnt = len(t)
        for c in t:
            if c not in need:
                need[c] = 0
            need[c] += 1

        left = 0
        ans = (0, sys.maxsize)
        for right in range(len(s)):
            if s[right] not in window:
                window[s[right]] = 0
            window[s[right]] += 1
            if s[right] in need and window[s[right]] <= need[s[right]]:
                need_cnt -= 1

            while need_cnt == 0:
                if right - left < ans[1] - ans[0]:
                    ans = (left, right)
                if s[left] in need and window[s[left]] <= need[s[left]]:
                    need_cnt += 1
                window[s[left]] -= 1
                left += 1
        return s[ans[0]:ans[1] + 1] if ans[1] != sys.maxsize else ""
